#include <cairo.h>
#ifndef CANVAS__H__ZHU
#define CANVAS__H__ZHU
struct Point
{
    int x_,y_;
    Point(int x = 0, int y = 0):x_(x),y_(y){}
};
class Shape
{
public:
    virtual Point Draw(cairo_t* cr)= 0;
    virtual Point e() = 0;
    virtual Point w() = 0;
    virtual Point s() = 0;
    virtual Point n() = 0;
    virtual Point ne() = 0;
    virtual Point nw() = 0;
    virtual Point se() = 0;
    virtual Point sw() = 0;
    virtual Point c () = 0;
    
};

class Rectangle:public Shape
{
public:
    Rectangle(Point top_left, Point bottom_right);
    virtual Point Draw(cairo_t* cr);
    virtual Point e(){
        return Point(bottom_right_.x_,(top_left_.y_ + bottom_right_.y_)/2);
    }
    virtual Point w(){
        return Point(top_left_.x_, (top_left_.y_ + bottom_right_.y_)/2);
    }
    virtual Point s(){
        return Point ((top_left_.x_ + bottom_right_.x_)/2, bottom_right_.y_);
    }
    virtual Point n(){
        return Point((top_left_.x_ + bottom_right_.x_)/2, top_left_.y_);
    }
    
    virtual Point ne(){return Point(bottom_right_.x_, top_left_.y_);}
    virtual Point nw(){return top_left_;}
    virtual Point se(){return bottom_right_;}
    virtual Point sw(){return Point(top_left_.x_, bottom_right_.y_);}
    virtual Point c (){
        return Point((top_left_.x_ + bottom_right_.x_)/2,
                     (top_left_.y_ + bottom_right_.y_)/2);
    }
private:
    Point top_left_;
    Point bottom_right_;
};
class Dot:public Shape
{
public:
    Dot(Point p);
    virtual Point Draw(cairo_t* cr);
    virtual Point e() {return p_;}
    virtual Point w() {return p_;}
    virtual Point s() {return p_;}
    virtual Point n() {return p_;}
    virtual Point ne(){return p_;}
    virtual Point nw(){return p_;}
    virtual Point se(){return p_;}
    virtual Point sw(){return p_;}
    virtual Point c(){return p_;}    
private:
    Point p_;
};

class Line:public Shape
{
public:
    Line(Point from, Point to);
    virtual Point Draw(cairo_t* cr);
    virtual Point e(){return Point(0,0);}
    virtual Point w(){return Point(0,0);}
    virtual Point s(){return Point(0,0);}
    virtual Point n(){return Point(0,0);}
    virtual Point ne(){return Point(0,0);}
    virtual Point nw(){return Point(0,0);}
    virtual Point se(){return Point(0,0);}
    virtual Point sw(){return Point(0,0);}
    virtual Point c() {
        return Point((from_.x_ + to_.x_)/2, (from_.y_ + to_.y_)/2);
    }
    
private:
    Point from_,to_;
};
class Canvas
{
public:
    Canvas(int width, int height);
    virtual ~Canvas();
    void SetCurrent(Point p){
        current_ = p;
    }
    Point Current()const{
        return current_;
    }
    Point Draw(Shape* s);
    
private:
    Point current_;
    int width_, height_;
    cairo_surface_t* surface_;
    cairo_t* cr_;
};
#endif
